#pragma once

#include "EntitiesCore.h"
#include "Intersection.h"
#include "Engine.h"

#include "dbg_render.h"

// Class for occluding objects
class Occluder {
public:
// singletone getter
	static inline Occluder &instance () {
		static Occluder occl;
		return occl;
	}

	inline void process () { frustumCulling(); occlusionCulling(); }

private:
	inline void frustumCulling () {
		for (u64 i = 0, size = EntitiesCore::entities().size(); i < size; ++i) {
			const Entity &ent = EntitiesCore::entities()[i];
			if (frustumTest(ent)) {
				ent.needDraw(true);
			} else {
				ent.needDraw(false);
			}
		}
	}

	// True - inside frustum, false - outside
	inline bool frustumTest (const Entity &ent) {
		Vector3f points[8];
		ent.getAabb().getPoints(points);
		//Vector3f position = ent.getFinalTransform().position();
		Vector3f position = ent.getTranslation();
		bool inside = false;
		for (int i = 0; i < 8; ++i) {
			points[i].add(position);
			if (engine.frustum.frustumTest(points[i])) {
				inside = true;
				r_dbg.draw_sphere(points[i], 0.1f, false);
				//break;
			} else {
				r_dbg.draw_sphere(points[i], 0.1f, true);
			}
		}
		return inside;
	}

	inline void occlusionCulling () { }
};